//
// client.cpp
// ~~~~~~~~~~
//
// Based on Asio Example code.
// The original code can be found in the AsioExampleCode folder.
// Comments in this file reflect changes made

#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <string.h>

using boost::asio::ip::udp;

int pain(int argc, char* argv[])
{
  // Represent the cube as an array of integers (x, y, z)
  int myCubePos[3] = {0};

  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: client <host>" << std::endl;
      return 1;
    }

    boost::asio::io_service io_service;

    udp::resolver resolver(io_service);
    udp::resolver::query query(udp::v4(), argv[1], "daytime");
    udp::endpoint receiver_endpoint = *resolver.resolve(query);

    udp::socket socket(io_service);
    socket.open(udp::v4());

    // Use a while loop to continually send data
    while (1) {
      /////////////////////////////////////////////////////
      // Send data
      /////////////////////////////////////////////////////
      // Allocate a character array for data to be sent
      boost::array<char, 128> send_buf = {{0}};
      // Read in one character
      std::cin.read(send_buf.data(),1);
      // Ignore new lines
      if(send_buf[0]=='\n') continue;

      socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);

      /////////////////////////////////////////////////////
      // Receive Data
      /////////////////////////////////////////////////////
      boost::array<char, 128> recv_buf;
      udp::endpoint sender_endpoint;
      size_t len = socket.receive_from(
        boost::asio::buffer(recv_buf), sender_endpoint);

      // Read the input and use it to move the cube
      // Controls:
      // w, s: Forward, Backward (X axis)
      // a, d: Left, Right (Y axis)
      // j, k: Up, Down (Z axis)
      switch(recv_buf[0]) {
	case 'w':
	  myCubePos[0]++;
	  break;
	case 'a':
	  myCubePos[1]--;
	  break;
	case 's':
	  myCubePos[0]--;
	  break;
	case 'd':
	  myCubePos[1]++;
	  break;
	case 'j':
	  myCubePos[2]++;
	  break;
	case 'k':
	  myCubePos[2]--;
	  break;
	default:
	  break;
      }
      // Display the updated position
      std::cout << "My cube position is: (" << myCubePos[0] << ", " << myCubePos[1] << ", " << myCubePos[2] << ")\n";
    }
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}
